/*
 * Middleware
 * Copyright (C) 2010/11
 * Riccardo Pulvirenti, Giuseppe Ravidà, Andrea Tino
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses
 */

/*!
 * File: workflow.cpp
 */
#include <boost/lexical_cast.hpp>

#include "workflow.hpp"
#include "utils.hpp"

using namespace middleware;

//-----------------------------------------------------------------------------
// Constructors and destructor
/* Default constructor */
Workflow::Workflow() {
	this->_id = this->createID();
	(this->_tasks).clear();
}
/* Copy constructor */
Workflow::Workflow(const Workflow& workflow) {
	this->_id = workflow._id;
	(this->_tasks).clear();
	Workflow::TaskCollectionConstIterator it;
	for (it = workflow._tasks.begin(); it < workflow._tasks.end(); it++)
		(this->_tasks).push_back(*it);
}
/* Destructor */
Workflow::~Workflow() {
	this->_tasks.clear();
}
//-----------------------------------------------------------------------------
// Public members
void Workflow::assign(Workflow::TaskCollectionConstIterator first,
		Workflow::TaskCollectionConstIterator last) {
	this->_tasks.clear();
	Workflow::TaskCollectionConstIterator it;
	for (it = first; it < last; it++) this->_tasks.push_back(*it);
}
/* Pushing back */
void Workflow::push_back(Workflow::ConstReference task) {
	this->_tasks.push_back(task);
}
/* Picking an element on id */
Workflow::Reference Workflow::at_id(TaskId id) throw(WorkflowException) {
	std::vector< TaskDescriptor >::iterator it;
	for (it = this->_tasks.begin(); it < this->_tasks.end(); it++)
		if (it->get_id() == id) return *it;
	// No element found, return an invalid TaskDescriptor
	throw WorkflowException("Not found!");
}
/* Indexer operator */
Workflow::Reference Workflow::operator[](Workflow::SizeType position) {
	return this->_tasks[position];
}
Workflow::ConstReference Workflow::operator[](Workflow::SizeType
		position) const {
	return this->_tasks[position];
}
/* Clearing */
void Workflow::clear() {
	(this->_tasks).clear();
}
/* Sizing */
Workflow::SizeType Workflow::size() const {
	return (this->_tasks).size();
}
/* Emptiness */
bool Workflow::emtpy() const {
	return (this->_tasks).empty();
}
/* To xml */
std::string Workflow::ToXml() const {
	using std::string;
	string xml = string("<Workflow>");
	xml += string("<ID>");
	xml += boost::lexical_cast<string>(this->_id);
	xml += string("</ID>");
	xml += string("<Tasks>");
	Workflow::TaskCollectionConstIterator it;
	for (it = this->_tasks.begin(); it < this->_tasks.end(); it++) {
		xml += it->ToXml();
	}
	xml += string("</Tasks>");
	xml += string("</Workflow>");
	return xml;
}
//-----------------------------------------------------------------------------
// Private members
WorkflowId Workflow::createID() {
	return (WorkflowId)utils::GetRandomIntegralNumberInt(kMinWorkflowID,
			kMaxWorkflowID);
}
